home *** CD-ROM | disk | FTP | other *** search
/ Sprite 1984 - 1993 / Sprite 1984 - 1993.iso / src / kernel / dev / ds5000.md / devGraphics.c < prev    next >
C/C++ Source or Header  |  1992-12-18  |  43KB  |  1,861 lines

  1. /* 
  2.  *  devGraphics.c --
  3.  *
  4.  *         This file contains machine-dependent routines for the graphics device.
  5.  *
  6.  *    Most of this assumes that you have a standard color frame buffer.
  7.  *    Support for the fancier graphics displays does not exist yet.
  8.  *
  9.  *    Copyright (C) 1989 Digital Equipment Corporation.
  10.  *    Permission to use, copy, modify, and distribute this software and
  11.  *    its documentation for any purpose and without fee is hereby granted,
  12.  *    provided that the above copyright notice appears in all copies.  
  13.  *    Digital Equipment Corporation makes no representations about the
  14.  *    suitability of this software for any purpose.  It is provided "as is"
  15.  *    without express or implied warranty.
  16.  */
  17.  
  18. #ifndef lint
  19. static char rcsid[] = "$Header: /cdrom/src/kernel/Cvsroot/kernel/dev/ds5000.md/devGraphics.c,v 1.7 91/09/20 18:27:02 mendel Exp $ SPRITE (DECWRL)";
  20. #endif not lint
  21.  
  22. #include <sprite.h>
  23. #include <machMon.h>
  24. #include <mach.h>
  25. #include <dev.h>
  26. #include <fs.h>
  27. #include <fsio.h>
  28. #include <sys.h>
  29. #include <sync.h>
  30. #include <timer.h>
  31. #include <dbg.h>
  32. #include <machAddrs.h>
  33. #include <console.h>
  34. #include <dc7085.h>
  35. #include <graphics.h>
  36. #include <vm.h>
  37. #include <vmMach.h>
  38. #include <dev/graphics.h>
  39. #include <devGraphicsInt.h>
  40.  
  41. /*
  42.  * Macro to translate from a time struct to milliseconds.
  43.  */
  44. #define TO_MS(time) ((time.seconds * 1000) + (time.microseconds / 1000))
  45.  
  46.  
  47. Boolean    devGraphicsOpen = FALSE;        /* TRUE => the mouse is open.*/
  48.                     /* Process waiting for select.*/
  49.  
  50. typedef struct {
  51.     char    *vendor;
  52.     char    *module;
  53.     int        romOffset;
  54.     int        type;
  55. } DisplayInfo;
  56.  
  57. DisplayInfo    configDisplays[] = {
  58.     {"DEC", "PMAG-BA", PMAGBA_ROM_OFFSET, PMAGBA},
  59.     {"DEC", "PMAG-DA", 0, PMAGBA},
  60. };
  61. int numConfigDisplays = sizeof(configDisplays) / sizeof(DisplayInfo);
  62.  
  63. /*
  64.  * Redefine MASTER_LOCK to be DISABLE_INTR for two reasons.  First, it
  65.  * is more efficient and sufficient on a uni-processor.  Second, MASTER_LOCK
  66.  * can cause deadlock because this file contains the routine which blits
  67.  * a character to the screen.  As a result no routine in here can do a printf
  68.  * underneath the MASTER_LOCK because the Blitc routine grabs the master lock.
  69.  * Once things are debugged and the printfs are removed it should be OK to use
  70.  * a TRUE master lock.
  71.  */
  72. #ifdef MASTER_LOCK
  73. #undef MASTER_LOCK
  74. #undef MASTER_UNLOCK
  75. #endif
  76. #define MASTER_LOCK(mutexPtr)    DISABLE_INTR()
  77. #define MASTER_UNLOCK(mutexPtr)    ENABLE_INTR()
  78.  
  79. /*
  80.  * These need to mapped into user space.
  81.  */
  82. static DevScreenInfo    scrInfoCached;
  83. static DevEvent        eventsCached[DEV_MAXEVQ] = {0};    
  84. static DevTimeCoord    tcsCached[MOTION_BUFFER_SIZE] = {0};
  85. static char        *frameBuffer = (char *) NIL;
  86.  
  87. static DevScreenInfo    *scrInfoPtr;
  88. static DevEvent        *events;
  89. static DevTimeCoord    *tcs;
  90.  
  91. static unsigned short    cursorBits [32];
  92.  
  93. Boolean            inKBDReset = FALSE;
  94.  
  95. Address            mappedAddrs[5];
  96.  
  97. /*
  98.  * DEBUGGING STUFF.
  99.  */
  100.  
  101. #define DEBUG_SIZE    256
  102. #define DEBUG_ADD    1
  103. #define DEBUG_UPDATE    2
  104. #define DEBUG_PTR(ptr) {             \
  105.     if (debugPtr == &debugArray[DEBUG_SIZE]) {    \
  106.     debugPtr = debugArray;            \
  107.     }                        \
  108.     ptr = debugPtr++;                \
  109. }
  110.  
  111. Boolean            devGraphicsDebug = TRUE;
  112. typedef struct {
  113.     int        type;
  114.     int        x;
  115.     int        y;
  116. } DebugInfo;
  117.  
  118. DebugInfo        debugArray[DEBUG_SIZE];
  119. DebugInfo        *debugPtr = debugArray;
  120.  
  121. int foo;
  122. int bar;
  123. /*
  124.  * END OF DEBUGGING STUFF.
  125.  */
  126.  
  127. MouseReport        lastRep;
  128. MouseReport        currentRep;
  129.  
  130. static unsigned char bgRgb[3];    /* background and foreground colors     */
  131. static unsigned char fgRgb[3];  /*     for the cursor. */
  132.  
  133. /*
  134.  * Keyboard defaults.
  135.  */
  136. static short divDefaults[15] = { 
  137.     LK_DOWN,    /* 0 doesn't exist */
  138.     LK_AUTODOWN, 
  139.     LK_AUTODOWN, 
  140.     LK_AUTODOWN, 
  141.     LK_DOWN,
  142.     LK_UPDOWN,   
  143.     LK_UPDOWN,   
  144.     LK_AUTODOWN, 
  145.     LK_AUTODOWN, 
  146.     LK_AUTODOWN, 
  147.     LK_AUTODOWN, 
  148.     LK_AUTODOWN, 
  149.     LK_AUTODOWN, 
  150.     LK_DOWN, 
  151.     LK_AUTODOWN 
  152. };
  153.  
  154. /* 
  155.  * Keyboard initialization string.
  156.  */
  157. short kbdInitString[] = {        /* reset any random keyboard stuff */
  158.     LK_AR_ENABLE,            /* we want autorepeat by default */
  159.     LK_CL_ENABLE,            /* keyclick */
  160.     0x84,                /* keyclick volume */
  161.     LK_KBD_ENABLE,            /* the keyboard itself */
  162.     LK_BELL_ENABLE,            /* keyboard bell */
  163.     0x84,                /* bell volume */
  164.     LK_LED_DISABLE,            /* keyboard leds */
  165.     LED_ALL
  166. };
  167.  
  168. #define KBD_INIT_LENGTH    sizeof(kbdInitString) / sizeof(short)
  169.  
  170.  
  171. /*
  172.  * The default cursor.  The X server does things in terms of the ds3100,
  173.  * which had the notion of A and B planes.  The LoadCursor routine
  174.  * converts this into the correct format.
  175.  */
  176.  
  177. unsigned short defCursor[32] = { 
  178. /* plane A */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
  179.           0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
  180. /* plane B */ 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF,
  181.               0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF, 0x00FF
  182.  
  183. };
  184. /*
  185.  * Font mask bits used by Blitc().
  186.  */
  187. static unsigned int fontmaskBits[16] = {
  188.     0x00000000,
  189.     0x00000001,
  190.     0x00000100,
  191.     0x00000101,
  192.     0x00010000,
  193.     0x00010001,
  194.     0x00010100,
  195.     0x00010101,
  196.     0x01000000,
  197.     0x01000001,
  198.     0x01000100,
  199.     0x01000101,
  200.     0x01010000,
  201.     0x01010001,
  202.     0x01010100,
  203.     0x01010101
  204. };
  205.  
  206. static Boolean initialized = FALSE;
  207.  
  208. /*
  209.  * Mutex to synchronize access.
  210.  */
  211. Sync_Semaphore graphicsMutex;
  212.  
  213. /*
  214.  * Token used to notify process that has graphics device open that events
  215.  * are available.
  216.  */
  217. ClientData    notifyToken;
  218.  
  219. /*
  220.  * Forward references.
  221.  */
  222. static void        InitScreenDefaults();
  223. static void        ScreenInit();
  224. static void        LoadCursor();
  225. static void        RestoreCursorColor();
  226. static void        CursorColor();
  227. static void        MouseInit();
  228. static void        KBDReset();
  229. static void        InitColorMap();
  230. static void        RAMDACInit();
  231. static void        LoadColorMap();
  232. static void         RecvIntr();
  233. static void        MouseEvent();
  234. static void        MouseButtons();
  235. static void        PosCursor();
  236. static void        XmitIntr();
  237. static void        Scroll();
  238. static void        Blitc();
  239.  
  240.  
  241. typedef struct ramdac {
  242.     unsigned char        *addrLowPtr;
  243.     unsigned char        *addrHighPtr;
  244.     volatile unsigned char    *regPtr;
  245.     volatile unsigned char    *colorMap;
  246. } Ramdac;
  247.  
  248. static Ramdac     ramdac;
  249. static int     planeMask;
  250. static int    displayType = UNKNOWN;
  251.  
  252.  
  253. /*
  254.  * ----------------------------------------------------------------------------
  255.  *
  256.  * DevGraphicsInit --
  257.  *
  258.  *    Initialize the mouse and the screen.
  259.  *
  260.  * Results:
  261.  *    None.
  262.  *
  263.  * Side effects:
  264.  *    The world is initialized.
  265.  *
  266.  * ----------------------------------------------------------------------------
  267.  */
  268. void
  269. DevGraphicsInit()
  270. {
  271.     Time        time;
  272.     int            i;
  273.     int            slot;
  274.     Mach_SlotInfo    slotInfo;
  275.     ReturnStatus    status;
  276.     char        *slotAddr;
  277.     DisplayInfo        *displayInfoPtr = (DisplayInfo *) NIL;
  278.  
  279.     Sync_SemInitDynamic(&graphicsMutex, "graphicsMutex");
  280.     for (i = 0; i < numConfigDisplays; i++) {
  281.     displayInfoPtr = &configDisplays[i];
  282.     for (slot = 0; slot < 3; slot++) {
  283.         slotAddr = (char *) MACH_IO_SLOT_ADDR(slot);
  284.         status = Mach_GetSlotInfo(slotAddr + displayInfoPtr->romOffset, 
  285.             &slotInfo);
  286.         if (status == SUCCESS) {
  287.         if ((!strcmp(slotInfo.vendor, displayInfoPtr->vendor)) && 
  288.             (!strcmp(slotInfo.module, displayInfoPtr->module))) {
  289.             displayType = displayInfoPtr->type;
  290.             break;
  291.         }
  292.         }
  293.     }
  294.     if (displayType != UNKNOWN) {
  295.         break;
  296.     }
  297.     }
  298.     switch (displayType) {
  299.     case UNKNOWN :
  300.         Mach_MonPrintf(
  301.         "Assuming you have one of those fancy graphics displays.\n");
  302.         displayType = PMAGDA;
  303.         break;
  304.     case PMAGBA:
  305.         Mach_MonPrintf("Color frame buffer in slot %d, (%s %s %s %s)\n",
  306.             slot, slotInfo.module, slotInfo.vendor,
  307.             slotInfo.revision, slotInfo.type);
  308.         break;
  309.     }
  310.     if (displayType == PMAGBA) {
  311.     ramdac.addrLowPtr = (unsigned char *) (slotAddr + PMAGBA_RAMDAC_OFFSET);
  312.     ramdac.addrHighPtr = (unsigned char *) 
  313.                 (slotAddr + PMAGBA_RAMDAC_OFFSET + 0x4);
  314.     ramdac.regPtr = (unsigned char *) 
  315.                 (slotAddr + PMAGBA_RAMDAC_OFFSET + 0x8);
  316.     ramdac.colorMap = (unsigned char *) 
  317.                 (slotAddr + PMAGBA_RAMDAC_OFFSET + 0xc);
  318.  
  319.     /*
  320.      * Initialize screen info.
  321.      */
  322.     scrInfoPtr = (DevScreenInfo *) MACH_UNCACHED_ADDR(&scrInfoCached);
  323.     events = (DevEvent *) MACH_UNCACHED_ADDR(eventsCached);
  324.     tcs = (DevTimeCoord *)  MACH_UNCACHED_ADDR(tcsCached);
  325.  
  326.     InitScreenDefaults(scrInfoPtr);
  327.     scrInfoPtr->eventQueue.events = events;
  328.     scrInfoPtr->eventQueue.tcs = tcs;
  329.     frameBuffer = (char *) (slotAddr + PMAGBA_BUFFER_OFFSET);
  330.     scrInfoPtr->bitmap = (char *) frameBuffer;
  331.     scrInfoPtr->cursorBits = (short *)(cursorBits);
  332.     Timer_GetRealTimeOfDay(&time, (int *) NIL, (Boolean *) NIL);
  333.     scrInfoPtr->eventQueue.timestampMS = TO_MS(time);
  334.     scrInfoPtr->eventQueue.eSize = DEV_MAXEVQ;
  335.     scrInfoPtr->eventQueue.eHead = scrInfoPtr->eventQueue.eTail = 0;
  336.     scrInfoPtr->eventQueue.tcSize = MOTION_BUFFER_SIZE;
  337.     scrInfoPtr->eventQueue.tcNext = 0;
  338.  
  339.     /*
  340.      * Initialize the color map, and the screen, and the mouse.
  341.      */
  342.     InitColorMap();
  343.     ScreenInit();
  344.     }
  345.     MouseInit();
  346.     Scroll();
  347.  
  348.     /*
  349.      * Init the "latest mouse report" structure
  350.      */
  351.     lastRep.state = 0;
  352.     lastRep.dx = 0;
  353.     lastRep.dy = 0;
  354.     lastRep.byteCount = 0;
  355.  
  356.  
  357.     /*
  358.      * Reset the keyboard.
  359.      */
  360.     if(!inKBDReset) {
  361.     KBDReset();
  362.     }
  363.  
  364.     if (displayType == PMAGBA) {
  365.     /*
  366.      * Clear any pending video interrupts.
  367.      */
  368.  
  369.     * ((int *) (slotAddr + PMAGBA_IREQ_OFFSET)) = 1;
  370.     }
  371.  
  372.     initialized = TRUE;
  373.  
  374.     bzero((char *) debugArray, sizeof(debugArray));
  375. }    
  376.  
  377.  
  378. /*
  379.  * ----------------------------------------------------------------------------
  380.  *
  381.  * InitScreenDefaults --
  382.  *
  383.  *    Set up default screen parameters.
  384.  *
  385.  * Results:
  386.  *    None.
  387.  *
  388.  * Side effects:
  389.  *    *scrInfoPtr is filled in with default screen parameters.
  390.  *
  391.  * ----------------------------------------------------------------------------
  392.  */
  393. static void
  394. InitScreenDefaults(scrInfoPtr)
  395.     DevScreenInfo    *scrInfoPtr;
  396. {
  397.     bzero((char *)scrInfoPtr, sizeof(DevScreenInfo));
  398.     scrInfoPtr->maxRow = 56;
  399.     scrInfoPtr->maxCol = 80;
  400.     scrInfoPtr->maxX = 1024;
  401.     scrInfoPtr->maxY = 864;
  402.     scrInfoPtr->maxCurX = 1023;
  403.     scrInfoPtr->maxCurY = 863;
  404.     scrInfoPtr->version = 11;
  405.     scrInfoPtr->mthreshold = 4;    
  406.     scrInfoPtr->mscale = 2;
  407.     scrInfoPtr->minCurX = -15;
  408.     scrInfoPtr->minCurY = -15;
  409. }
  410.  
  411.  
  412. /*
  413.  * ----------------------------------------------------------------------------
  414.  *
  415.  * ScreenInit --
  416.  *
  417.  *    Initialize the screen.
  418.  *
  419.  * Results:
  420.  *    None.
  421.  *
  422.  * Side effects:
  423.  *    The screen is initialized.
  424.  *
  425.  * ----------------------------------------------------------------------------
  426.  */
  427. static void
  428. ScreenInit()
  429. {
  430.     /*
  431.      * Home the cursor.
  432.      * We want an LSI terminal emulation.  We want the graphics
  433.      * terminal to scroll from the bottom. So start at the bottom.
  434.      */
  435.     scrInfoPtr->row = 55;
  436.     scrInfoPtr->col = 0;
  437.  
  438.     /*
  439.      * Load the cursor with the default values
  440.      *
  441.      */
  442.     LoadCursor(defCursor);
  443.  
  444.     /*
  445.      * Reset keyboard to default state.
  446.      */
  447.      if(!inKBDReset) {
  448.      KBDReset();
  449.      }
  450. }
  451.  
  452.  
  453. /*
  454.  * ----------------------------------------------------------------------------
  455.  *
  456.  * LoadCursor --
  457.  *
  458.  *    Routine to load the cursor Sprite pattern.  The hardware cursor is
  459.  *    64x64x2.  Each byte loaded into the bt459 is 4 pixels (2 bits each),
  460.  *    and the most-significant bit is the leftmost on the screen.
  461.  *    The parameter to this routine is an array of bytes, in the format
  462.  *    used by the ds3100.  The array can be thought of as two arrays
  463.  *    of 16-bit words each with 16 words.  The first array is one bit
  464.  *     for each pixel, and the second array is the other bit.  Also, the
  465.  *    least-significant bit of the byte is the leftmost on the screen, and
  466.  *    the cursor is 16x16.  This routine has to convert between the
  467.  *    two formats, hence the mess.  Any unused bits in the hardware
  468.  *    cursor are set to 0.
  469.  *
  470.  * Results:
  471.  *    None.
  472.  *
  473.  * Side effects:
  474.  *    The cursor is loaded into the hardware cursor.
  475.  *
  476.  * ----------------------------------------------------------------------------
  477.  */
  478. static void
  479. LoadCursor(curPtr)
  480.     unsigned char *curPtr;
  481. {
  482.     register int i, j;
  483.     int addr;
  484.     unsigned char value, a, b;
  485.     unsigned char *aPtr, *bPtr;
  486.  
  487.     aPtr = curPtr;
  488.     bPtr = curPtr + 32;
  489.     addr = 0x400;
  490.     *ramdac.addrHighPtr = (addr >> 8);
  491.     *ramdac.addrLowPtr = (addr & 0xff);
  492.     Mach_EmptyWriteBuffer();
  493.     for (i = 0; i < 16; i++) {
  494.     for (j = 0; j < 4; j += 2) {
  495.         a = *aPtr;
  496.         b = *bPtr;
  497.         value = ((a << 7) & 0x80) |
  498.             ((b << 6) & 0x40) |
  499.             ((a << 4) & 0x20) |
  500.             ((b << 3) & 0x10) |
  501.             ((a << 1) & 0x08) |
  502.             ((b << 0) & 0x04) |
  503.             ((a >> 2) & 0x02) |
  504.             ((b >> 3) & 0x01);
  505.         *ramdac.regPtr = value;
  506.         Mach_EmptyWriteBuffer();
  507.         value = ((a << 3) & 0x80) |
  508.             ((b << 2) & 0x40) |
  509.             ((a << 0) & 0x20) |
  510.             ((b >> 1) & 0x10) |
  511.             ((a >> 3) & 0x08) |
  512.             ((b >> 4) & 0x04) |
  513.             ((a >> 6) & 0x02) |
  514.             ((b >> 7) & 0x01);
  515.         *ramdac.regPtr = value;
  516.         Mach_EmptyWriteBuffer();
  517.         aPtr++;
  518.         bPtr++;
  519.     }
  520.     for(; j < 16; j++) {
  521.         *ramdac.regPtr = 0;
  522.         Mach_EmptyWriteBuffer();
  523.     }
  524.     }
  525.     for (; i < 64; i++) {
  526.     for (j = 0; j < 16; j++) {
  527.         *ramdac.regPtr = 0;
  528.         Mach_EmptyWriteBuffer();
  529.     }
  530.     }
  531. }
  532.  
  533.  
  534. /*
  535.  * ----------------------------------------------------------------------------
  536.  *
  537.  * RestoreCursorColor --
  538.  *
  539.  *    Routine to restore the color of the cursor.
  540.  *
  541.  * Results:
  542.  *    None.
  543.  *
  544.  * Side effects:
  545.  *    None.
  546.  *
  547.  * ----------------------------------------------------------------------------
  548.  */
  549. static void
  550. RestoreCursorColor()
  551. {
  552.     register int i;
  553.  
  554.  
  555.     *ramdac.addrHighPtr = 0x1;
  556.     *ramdac.addrLowPtr = 0x81;
  557.     Mach_EmptyWriteBuffer();
  558.     for (i=0; i < 3; i++) {  
  559.     *ramdac.regPtr = bgRgb[i];
  560.     Mach_EmptyWriteBuffer();
  561.     }
  562.  
  563.     *ramdac.addrHighPtr = 0x1;
  564.     *ramdac.addrLowPtr = 0x82;
  565.     Mach_EmptyWriteBuffer();
  566.     for (i=0; i < 3; i++) {  
  567.     *ramdac.regPtr = fgRgb[i];
  568.     Mach_EmptyWriteBuffer();
  569.     }
  570. }
  571.  
  572.  
  573. /*
  574.  * ----------------------------------------------------------------------------
  575.  *
  576.  * CursorColor --
  577.  *
  578.  *    Set the color of the cursor.
  579.  *
  580.  * Results:
  581.  *    None.
  582.  *
  583.  * Side effects:
  584.  *    None.
  585.  *
  586.  * ----------------------------------------------------------------------------
  587.  */
  588. static void
  589. CursorColor(color)
  590.     unsigned int color[];
  591. {
  592.     register int i, j;
  593.     for (i = 0; i < 3; i++) {
  594.     bgRgb[i] = (unsigned char )(color[i] >> 8);
  595.     }
  596.     for (j = 0; j < 3; j++) {
  597.     fgRgb[i] = (unsigned char )(color[j] >> 8);
  598.     }
  599.     RestoreCursorColor();
  600. }
  601.  
  602.  
  603. /*
  604.  * ----------------------------------------------------------------------------
  605.  *
  606.  * MouseInit --
  607.  *
  608.  *    Initialize the mouse.
  609.  *
  610.  * Results:
  611.  *    None.
  612.  *
  613.  * Side effects:
  614.  *    None.
  615.  *
  616.  * ----------------------------------------------------------------------------
  617.  */
  618. static void
  619. MouseInit()
  620. {
  621.     int    id_byte1, id_byte2, id_byte3, id_byte4;
  622.  
  623.     /*
  624.      * Initialize the mouse.
  625.      */
  626.     DevDC7085MouseInit();
  627.     DevDC7085MousePutCh(MOUSE_SELF_TEST);
  628.     id_byte1 = DevDC7085MouseGetCh();
  629.     if (id_byte1 < 0) {
  630.     printf("MouseInit: Timeout on 1st byte of self-test report\n");
  631.     return;
  632.     }
  633.     id_byte2 = DevDC7085MouseGetCh();
  634.     if (id_byte2 < 0) {
  635.     printf("MouseInit: Timeout on 2nd byte of self-test report\n");
  636.     return;
  637.     }
  638.     id_byte3 = DevDC7085MouseGetCh();
  639.     if (id_byte3 < 0) {
  640.     printf("MouseInit: Timeout on 3rd byte of self-test report\n");
  641.     return;
  642.     }
  643.     id_byte4 = DevDC7085MouseGetCh();
  644.     if (id_byte4 < 0) {
  645.     printf("MouseInit: Timeout on 4th byte of self-test report\n");
  646.     return;
  647.     }
  648.     if ((id_byte2 & 0x0f) != 0x2) {
  649.     printf("MouseInit: We don't have a mouse!!!\n");
  650.     }
  651.     DevDC7085MousePutCh(MOUSE_INCREMENTAL);
  652. }
  653.  
  654.  
  655. /*
  656.  * ----------------------------------------------------------------------------
  657.  *
  658.  * KBDReset --
  659.  *
  660.  *    Reset the keyboard to default characteristics.
  661.  *
  662.  * Results:
  663.  *    None.
  664.  *
  665.  * Side effects:
  666.  *    None.
  667.  *
  668.  * ----------------------------------------------------------------------------
  669.  */
  670. static void
  671. KBDReset()
  672. {
  673.     register int i;
  674.  
  675.     inKBDReset = TRUE;
  676.     DevDC7085KBDPutc(LK_DEFAULTS);
  677.     for (i=1; i < 15; i++) {
  678.     DevDC7085KBDPutc(divDefaults[i] | (i << 3));
  679.     }
  680.     for (i = 0; i < KBD_INIT_LENGTH; i++) {
  681.     DevDC7085KBDPutc ((int)kbdInitString[i]);
  682.     }
  683.     inKBDReset = FALSE;
  684. }
  685.  
  686.  
  687. /*
  688.  * ----------------------------------------------------------------------------
  689.  *
  690.  * InitColorMap --
  691.  *
  692.  *    Initialize the color map.
  693.  *
  694.  * Results:
  695.  *    None.
  696.  *
  697.  * Side effects:
  698.  *    The colormap is initialized appropriately whether it is color or 
  699.  *    monochrome.
  700.  *
  701.  * ----------------------------------------------------------------------------
  702.  */
  703. static void
  704. InitColorMap()
  705. {
  706.     register int i;
  707.  
  708.     RAMDACInit();
  709.  
  710.     *ramdac.addrHighPtr = 0;
  711.     *ramdac.addrLowPtr = 0;
  712.     Mach_EmptyWriteBuffer();
  713.     *ramdac.colorMap = 0;
  714.     Mach_EmptyWriteBuffer();
  715.     *ramdac.colorMap = 0;
  716.     Mach_EmptyWriteBuffer();
  717.     *ramdac.colorMap = 0;
  718.     Mach_EmptyWriteBuffer();
  719.     for(i = 1; i < 256; i++) {
  720.     *ramdac.colorMap = 0xff;
  721.     Mach_EmptyWriteBuffer();
  722.     *ramdac.colorMap = 0xff;
  723.     Mach_EmptyWriteBuffer();
  724.     *ramdac.colorMap = 0xff;
  725.     Mach_EmptyWriteBuffer();
  726.     }
  727.     for (i = 0;i < 3; i++) {
  728.     bgRgb[i] = 0x00;
  729.     fgRgb[i] = 0xff;
  730.     }
  731.  
  732. }
  733.  
  734.  
  735. /*
  736.  * ----------------------------------------------------------------------------
  737.  *
  738.  * RAMDACInit --
  739.  *
  740.  *    Initialize the RAMDAC.
  741.  *
  742.  * Results:
  743.  *    None.
  744.  *
  745.  * Side effects:
  746.  *    None.
  747.  *
  748.  * ----------------------------------------------------------------------------
  749.  */
  750. static void
  751. RAMDACInit()
  752. {
  753.  
  754. #if 0
  755.     /*
  756.      * Set up command register 0.
  757.      */
  758.     *ramdac.addrHighPtr = 0x2;
  759.     *ramdac.addrLowPtr = 0x1;
  760.     Mach_EmptyWriteBuffer();
  761.     *ramdac.regPtr = 0x80;
  762.     /*
  763.      * See note on page 4 of PMAG-BA doc.
  764.      */
  765.     {
  766.     volatile char    *addr = (char *) ROM2_ADDR;
  767.     *addr = 1;
  768.     }
  769.     /*
  770.      * Set up command register 1.
  771.      */
  772.     *ramdac.addrHighPtr = 0x2;
  773.     *ramdac.addrLowPtr = 0x2;
  774.     Mach_EmptyWriteBuffer();
  775.     *ramdac.regPtr = 0x00;
  776.     /*
  777.      * Set up command register 2.
  778.      */
  779.     *ramdac.addrHighPtr = 0x2;
  780.     *ramdac.addrLowPtr = 0x3;
  781.     Mach_EmptyWriteBuffer();
  782.     *ramdac.regPtr = 0x00;
  783.  
  784. #endif
  785.     /*
  786.      * Set up cursor command register. Enable both planes of the cursor
  787.      * and stop the damn blinking.
  788.      */
  789.     *ramdac.addrHighPtr = 0x3;
  790.     *ramdac.addrLowPtr = 0x0;
  791.     Mach_EmptyWriteBuffer();
  792.     *ramdac.regPtr = 0xc0;
  793.     Mach_EmptyWriteBuffer();
  794. }
  795.  
  796.  
  797.  
  798.  
  799. /*
  800.  * ----------------------------------------------------------------------------
  801.  *
  802.  * LoadColorMap --
  803.  *
  804.  *    Load the color map.
  805.  *
  806.  * Results:
  807.  *    None.
  808.  *
  809.  * Side effects:
  810.  *    The color map is loaded.
  811.  *
  812.  * ----------------------------------------------------------------------------
  813.  */
  814. static void
  815. LoadColorMap(ptr)
  816.     DevColorMap  *ptr;
  817. {
  818.     if(ptr->index > 256) {
  819.      return;
  820.     }
  821.  
  822.     *ramdac.addrHighPtr = 0x0;
  823.     *ramdac.addrLowPtr = ptr->index;
  824.     Mach_EmptyWriteBuffer();
  825.     *ramdac.colorMap = ptr->entry.red;
  826.     Mach_EmptyWriteBuffer();
  827.     *ramdac.colorMap = ptr->entry.green;
  828.     Mach_EmptyWriteBuffer();
  829.     *ramdac.colorMap = ptr->entry.blue;
  830.     Mach_EmptyWriteBuffer();
  831. }
  832.  
  833. static Boolean    consoleCmdDown = FALSE;
  834.  
  835.  
  836. /*
  837.  *----------------------------------------------------------------------
  838.  *
  839.  * DevGraphicsKbdIntr --
  840.  *
  841.  *    Process a received character.
  842.  *
  843.  * Results:
  844.  *    None.
  845.  *
  846.  * Side effects:
  847.  *    Events added to the queue.
  848.  *
  849.  *----------------------------------------------------------------------
  850.  */
  851. void
  852. DevGraphicsKbdIntr(ch)
  853.     unsigned char ch;
  854. {
  855.     int        i;
  856.     Time    time;
  857.     DevEvent    *eventPtr;
  858.     
  859.     if (ch == LK_POWER_ERROR || ch == LK_KDOWN_ERROR ||
  860.     ch == LK_INPUT_ERROR || ch == LK_OUTPUT_ERROR) {
  861.     if(!inKBDReset) {
  862.         printf("\n: RecvIntr: keyboard error,code=%x", ch);
  863.         KBDReset();
  864.     }
  865.     return;
  866.     }
  867.     if (ch < LK_LOWEST) {
  868.        return;
  869.     }
  870.     if (ch == KEY_UP) {
  871.     consoleCmdDown = FALSE;
  872.     } else if (ch == KEY_COMMAND) {
  873.     consoleCmdDown = TRUE;
  874.     } else if (consoleCmdDown) {
  875.     int asciiChar;
  876.  
  877.     consoleCmdDown = FALSE;
  878.     asciiChar = (int) DevDC7085TranslateKey(ch, FALSE, FALSE);
  879.     if (asciiChar != -1) {
  880.         Dev_InvokeConsoleCmd(asciiChar);
  881.         return;
  882.     }
  883.     }
  884.  
  885.     /*
  886.      * See if there is room in the queue.
  887.      */
  888.     i = DEV_EVROUND(scrInfoPtr->eventQueue.eTail + 1);
  889.     if (i == scrInfoPtr->eventQueue.eHead) {
  890.     return;
  891.     }
  892.  
  893.     /*
  894.      * Add the event to the queue.
  895.      */
  896.     eventPtr = &events[scrInfoPtr->eventQueue.eTail];
  897.     eventPtr->type = DEV_BUTTON_RAW_TYPE;
  898.     eventPtr->device = DEV_KEYBOARD_DEVICE;
  899.     eventPtr->x = scrInfoPtr->mouse.x;
  900.     eventPtr->y = scrInfoPtr->mouse.y;
  901.     Timer_GetRealTimeOfDay(&time, (int *) NIL, (Boolean *) NIL);
  902.     eventPtr->time = TO_MS(time);
  903.     eventPtr->key = ch;
  904.     scrInfoPtr->eventQueue.eTail = i;
  905.     dev_LastConsoleInput = time;
  906.     Fsio_DevNotifyReader(notifyToken);
  907. }
  908.  
  909.  
  910. /*
  911.  *----------------------------------------------------------------------
  912.  *
  913.  * DevGraphicsMouseIntr --
  914.  *
  915.  *    Process a received mouse character.
  916.  *
  917.  * Results:
  918.  *    None.
  919.  *
  920.  * Side effects:
  921.  *    Events added to the queue.
  922.  *
  923.  *----------------------------------------------------------------------
  924.  */
  925. void
  926. DevGraphicsMouseIntr(ch)
  927.     unsigned char ch;
  928. {
  929.     MouseReport    *newRepPtr;
  930.  
  931.     newRepPtr = ¤tRep;
  932.     newRepPtr->byteCount++;
  933.     if (ch & MOUSE_START_FRAME) {
  934.     /*
  935.      * The first mouse report byte (button state).
  936.      */
  937.     newRepPtr->state = ch;
  938.     if (newRepPtr->byteCount > 1) {
  939.         newRepPtr->byteCount = 1;
  940.     }
  941.     } else if (newRepPtr->byteCount == 2) {
  942.     /*
  943.      * The second mouse report byte (delta x).
  944.      */
  945.     newRepPtr->dx = ch;
  946.     } else if (newRepPtr->byteCount == 3) {
  947.     /*
  948.      * The final mouse report byte (delta y).
  949.      */
  950.     newRepPtr->dy = ch;
  951.     newRepPtr->byteCount = 0;
  952.     if (newRepPtr->dx != 0 || newRepPtr->dy != 0) {
  953.         /*
  954.          * If the mouse moved, post a motion event.
  955.          */
  956.         MouseEvent(newRepPtr);
  957.     }
  958.     MouseButtons(newRepPtr);
  959.     }
  960. }
  961.  
  962.  
  963. /*
  964.  *----------------------------------------------------------------------
  965.  *
  966.  * MouseEvent --
  967.  *
  968.  *    Process a mouse event.
  969.  *
  970.  * Results:
  971.  *    None.
  972.  *
  973.  * Side effects:
  974.  *    An event is added to the event queue.
  975.  *
  976.  *----------------------------------------------------------------------
  977.  */
  978. static void
  979. MouseEvent(newRepPtr) 
  980.     MouseReport    *newRepPtr;
  981. {
  982.     Time    time;
  983.     unsigned    milliSec;
  984.     int        i;
  985.     DevEvent    *eventPtr;
  986.  
  987.     Timer_GetRealTimeOfDay(&time, (int *) NIL, (Boolean *) NIL);
  988.     milliSec = TO_MS(time);
  989.  
  990.     /*
  991.      * Check to see if we have to accelerate the mouse
  992.      */
  993.     if (scrInfoPtr->mscale >=0) {
  994.     if (newRepPtr->dx >= scrInfoPtr->mthreshold) {
  995.         newRepPtr->dx +=
  996.             (newRepPtr->dx - scrInfoPtr->mthreshold) * scrInfoPtr->mscale;
  997.     }
  998.     if (newRepPtr->dy >= scrInfoPtr->mthreshold) {
  999.         newRepPtr->dy +=
  1000.         (newRepPtr->dy - scrInfoPtr->mthreshold) * scrInfoPtr->mscale;
  1001.     }
  1002.     }
  1003.     
  1004.     /*
  1005.      * Update mouse position
  1006.      */
  1007.     if( newRepPtr->state & MOUSE_X_SIGN) {
  1008.     scrInfoPtr->mouse.x += newRepPtr->dx;
  1009.     if (scrInfoPtr->mouse.x > scrInfoPtr->maxCurX) {
  1010.         scrInfoPtr->mouse.x = scrInfoPtr->maxCurX;
  1011.     }
  1012.     } else {
  1013.     scrInfoPtr->mouse.x -= newRepPtr->dx;
  1014.     if (scrInfoPtr->mouse.x < scrInfoPtr->minCurX) {
  1015.         scrInfoPtr->mouse.x = scrInfoPtr->minCurX;
  1016.     }
  1017.     }
  1018.     if( newRepPtr->state & MOUSE_Y_SIGN) {
  1019.     scrInfoPtr->mouse.y -= newRepPtr->dy;
  1020.     if (scrInfoPtr->mouse.y < scrInfoPtr->minCurY) {
  1021.         scrInfoPtr->mouse.y = scrInfoPtr->minCurY;
  1022.     }
  1023.     } else {
  1024.     scrInfoPtr->mouse.y += newRepPtr->dy;
  1025.     if (scrInfoPtr->mouse.y > scrInfoPtr->maxCurY) {
  1026.         scrInfoPtr->mouse.y = scrInfoPtr->maxCurY;
  1027.     }
  1028.     }
  1029.     if (devGraphicsOpen) {
  1030.     /*
  1031.      * Move the hardware cursor.
  1032.      */
  1033.     PosCursor(scrInfoPtr->mouse.x, scrInfoPtr->mouse.y);
  1034.     }
  1035.     /*
  1036.      * Store the motion event in the motion buffer.
  1037.      */
  1038.     tcs[scrInfoPtr->eventQueue.tcNext].time = milliSec;
  1039.     tcs[scrInfoPtr->eventQueue.tcNext].x = scrInfoPtr->mouse.x;
  1040.     tcs[scrInfoPtr->eventQueue.tcNext].y = scrInfoPtr->mouse.y;
  1041.     scrInfoPtr->eventQueue.tcNext++;
  1042.     if (scrInfoPtr->eventQueue.tcNext >= MOTION_BUFFER_SIZE) {
  1043.     scrInfoPtr->eventQueue.tcNext = 0;
  1044.     }
  1045.     if (scrInfoPtr->mouse.y < scrInfoPtr->mbox.bottom &&
  1046.     scrInfoPtr->mouse.y >=  scrInfoPtr->mbox.top &&
  1047.     scrInfoPtr->mouse.x < scrInfoPtr->mbox.right &&
  1048.     scrInfoPtr->mouse.x >=  scrInfoPtr->mbox.left) {
  1049.     return;
  1050.     }
  1051.  
  1052.     scrInfoPtr->mbox.bottom = 0;
  1053.     if (DEV_EVROUND(scrInfoPtr->eventQueue.eTail + 1) == scrInfoPtr->eventQueue.eHead) {
  1054.     return;
  1055.     }
  1056.  
  1057.     i = DEV_EVROUND(scrInfoPtr->eventQueue.eTail -1);
  1058.     if ((scrInfoPtr->eventQueue.eTail != scrInfoPtr->eventQueue.eHead) && 
  1059.         (i != scrInfoPtr->eventQueue.eHead)) {
  1060.     DevEvent    *eventPtr;
  1061.     eventPtr = &events[i];
  1062.     if(eventPtr->type == DEV_MOTION_TYPE) {
  1063.         /*
  1064.          * On the ds5000/200 there is some kind of bug when doing partial
  1065.          * writes.  Sometimes the x,y fields of one event are in the first
  1066.          * word of a cache line, and the x,y fields of the next event are
  1067.          * in the last word of the same cache line.  In this case the line
  1068.          * is probably in the cache because the X server just read it, but
  1069.          * the write done by the kernel to the last word in the cache line
  1070.          * will not be seen by the Xserver, causing the mouse to jump.
  1071.          * It is almost as if the kernel is bypassing the cache and writing
  1072.          * directly to memory.  If we read the word before writing it the
  1073.          * problem goes away.  JHH 2/7/90.
  1074.          */
  1075.         eventPtr->x = scrInfoPtr->mouse.x;
  1076.         eventPtr->y = scrInfoPtr->mouse.y;
  1077.         eventPtr->time = milliSec;
  1078.         eventPtr->device = DEV_MOUSE_DEVICE;
  1079.         return;
  1080.     }
  1081.     } 
  1082.     /*
  1083.      * Put event into queue and wakeup any waiters.
  1084.      */
  1085.     eventPtr = &events[scrInfoPtr->eventQueue.eTail];
  1086.     /*
  1087.      * See comment above.
  1088.      */
  1089.     eventPtr->type = DEV_MOTION_TYPE;
  1090.     eventPtr->time = milliSec;
  1091.     eventPtr->x = scrInfoPtr->mouse.x;
  1092.     eventPtr->y = scrInfoPtr->mouse.y;
  1093.     eventPtr->device = DEV_MOUSE_DEVICE;
  1094.     scrInfoPtr->eventQueue.eTail = DEV_EVROUND(scrInfoPtr->eventQueue.eTail + 1);
  1095.     dev_LastConsoleInput = time;
  1096.     if (devGraphicsOpen) {
  1097.     Fsio_DevNotifyReader(notifyToken);
  1098.     }
  1099. }
  1100.  
  1101.  
  1102. /*
  1103.  *----------------------------------------------------------------------
  1104.  *
  1105.  * MouseButtons --
  1106.  *
  1107.  *    Process mouse buttons.
  1108.  *
  1109.  * Results:
  1110.  *    None.
  1111.  *
  1112.  * Side effects:
  1113.  *    None.
  1114.  *
  1115.  *----------------------------------------------------------------------
  1116.  */
  1117. static void
  1118. MouseButtons(newRepPtr)
  1119.     MouseReport    *newRepPtr;
  1120. {
  1121.     static char temp, oldSwitch, newSwitch;
  1122.     int        i, j;
  1123.     DevEvent    *eventPtr;
  1124.     Time    time;
  1125.  
  1126.     newSwitch = newRepPtr->state & 0x07;
  1127.     oldSwitch = lastRep.state & 0x07;
  1128.     
  1129.     temp = oldSwitch ^ newSwitch;
  1130.     if (temp != 0) {
  1131.     for (j = 1; j < 8; j <<= 1) {
  1132.         if ((j & temp) == 0) {
  1133.         continue;
  1134.         }
  1135.  
  1136.         /*
  1137.          * Check for room in the queue
  1138.          */
  1139.         i = DEV_EVROUND(scrInfoPtr->eventQueue.eTail+1);
  1140.         if (i == scrInfoPtr->eventQueue.eHead) {
  1141.         return;
  1142.         }
  1143.  
  1144.         /*
  1145.          * Put event into queue.
  1146.          */
  1147.         eventPtr = &events[scrInfoPtr->eventQueue.eTail];
  1148.         switch (j) {
  1149.         case RIGHT_BUTTON:
  1150.             eventPtr->key = DEV_EVENT_RIGHT_BUTTON;
  1151.             break;
  1152.         case MIDDLE_BUTTON:
  1153.             eventPtr->key = DEV_EVENT_MIDDLE_BUTTON;
  1154.             break;
  1155.         case LEFT_BUTTON:
  1156.             eventPtr->key = DEV_EVENT_LEFT_BUTTON;
  1157.             break;
  1158.         }
  1159.         if (newSwitch & j) {
  1160.         eventPtr->type = DEV_BUTTON_DOWN_TYPE;
  1161.         } else {
  1162.         eventPtr->type = DEV_BUTTON_UP_TYPE;
  1163.         }
  1164.         eventPtr->device = DEV_MOUSE_DEVICE;
  1165.  
  1166.         Timer_GetRealTimeOfDay(&time, (int *) NIL, (Boolean *) NIL);
  1167.         eventPtr->time = TO_MS(time);
  1168.         eventPtr->x = scrInfoPtr->mouse.x;
  1169.         eventPtr->y = scrInfoPtr->mouse.y;
  1170.     }
  1171.     scrInfoPtr->eventQueue.eTail = i;
  1172.     if (devGraphicsOpen) {
  1173.         Fsio_DevNotifyReader(notifyToken);
  1174.     }
  1175.  
  1176.     /* 
  1177.      * Update the last report 
  1178.      */
  1179.     lastRep = currentRep;
  1180.     scrInfoPtr->mswitches = newSwitch;
  1181.     }
  1182. }
  1183.  
  1184.  
  1185. /*
  1186.  *----------------------------------------------------------------------
  1187.  *
  1188.  * PosCursor --
  1189.  *
  1190.  *    Postion the cursor.
  1191.  *
  1192.  * Results:
  1193.  *    None.
  1194.  *
  1195.  * Side effects:
  1196.  *    None.
  1197.  *
  1198.  *----------------------------------------------------------------------
  1199.  */
  1200. static void
  1201. PosCursor(x, y)
  1202.     register int x,y;
  1203. {
  1204.     int        pos;
  1205.     if( y < scrInfoPtr->minCurY || y > scrInfoPtr->maxCurY ) {
  1206.     y = scrInfoPtr->maxCurY;
  1207.     }
  1208.     if(x < scrInfoPtr->minCurX || x > scrInfoPtr->maxCurX) {
  1209.     x = scrInfoPtr->maxCurX;
  1210.     }
  1211.     scrInfoPtr->cursor.x = x;        /* keep track of real cursor*/
  1212.     scrInfoPtr->cursor.y = y;        /* position, indep. of mouse*/
  1213.  
  1214.     pos = x + 241 - 52 + 31;
  1215.     *ramdac.addrHighPtr = 0x3;
  1216.     *ramdac.addrLowPtr = 0x1;
  1217.     Mach_EmptyWriteBuffer();
  1218.     *ramdac.regPtr = (pos & 0xff);
  1219.     *ramdac.addrHighPtr = 0x3;
  1220.     *ramdac.addrLowPtr = 0x2;
  1221.     Mach_EmptyWriteBuffer();
  1222.     *ramdac.regPtr = ((pos >> 8) & 0xff);
  1223.     Mach_EmptyWriteBuffer();
  1224.  
  1225.     pos = y + 36 - 32 + 31;
  1226.     *ramdac.addrHighPtr = 0x3;
  1227.     *ramdac.addrLowPtr = 0x3;
  1228.     Mach_EmptyWriteBuffer();
  1229.     *ramdac.regPtr = (pos & 0xff);
  1230.     *ramdac.addrHighPtr = 0x3;
  1231.     *ramdac.addrLowPtr = 0x4;
  1232.     Mach_EmptyWriteBuffer();
  1233.     *ramdac.regPtr = ((pos >> 8) & 0xff);
  1234.     Mach_EmptyWriteBuffer();
  1235. }
  1236.  
  1237.  
  1238. /*
  1239.  *----------------------------------------------------------------------
  1240.  *
  1241.  * Scroll --
  1242.  *
  1243.  *    Scroll the screen.
  1244.  *
  1245.  * Results:
  1246.  *    None.
  1247.  *
  1248.  * Side effects:
  1249.  *    None.
  1250.  *
  1251.  *----------------------------------------------------------------------
  1252.  */
  1253. static void
  1254. Scroll()
  1255. {
  1256.     int    line;
  1257.     register int *dest, *src;
  1258.     register int *end;
  1259.     register int temp0,temp1,temp2,temp3;
  1260.     register int i, scanInc, lineCount;
  1261.  
  1262.  
  1263.     if (displayType != PMAGBA) {
  1264.     return;
  1265.     }
  1266.     /*
  1267.      *  The following is an optimization to cause the scrolling 
  1268.      *  of text to be memory limited.  Basically the writebuffer is 
  1269.      *  4 words (32 bits ea.) long so to achieve maximum speed we 
  1270.      *  read and write in multiples of 4 words. We also limit the 
  1271.      *  size to be 80 characters for more speed. 
  1272.      */
  1273.     lineCount = 40;
  1274.     scanInc = 96;
  1275.     line = 1920 * 8;
  1276.     src = (int *)(frameBuffer+line);
  1277.     dest = (int *)(frameBuffer);
  1278.     end = (int *)(frameBuffer+ (60 * line) - line);
  1279.     do {
  1280.     i = 0;
  1281.     do {
  1282.         temp0 = src[0];
  1283.         temp1 = src[1];
  1284.         temp2 = src[2];
  1285.         temp3 = src[3];
  1286.         dest[0] = temp0;
  1287.         dest[1] = temp1;
  1288.         dest[2] = temp2;
  1289.         dest[3] = temp3;
  1290.         dest += 4;
  1291.         src += 4;
  1292.         i++;
  1293.     } while(i < lineCount);
  1294.     src += scanInc;
  1295.     dest += scanInc;
  1296.     } while(src < end);
  1297.  
  1298.     /* 
  1299.      * Now zero out the last two lines 
  1300.      */
  1301.     bzero(frameBuffer+(scrInfoPtr->row * line),  3 * line);
  1302. }
  1303.  
  1304.  
  1305. /*
  1306.  *----------------------------------------------------------------------
  1307.  *
  1308.  * Dev_GraphicsPutc --
  1309.  *
  1310.  *    Write a character to the console.
  1311.  *
  1312.  * Results:
  1313.  *    None.
  1314.  *
  1315.  * Side effects:
  1316.  *    None.
  1317.  *
  1318.  *----------------------------------------------------------------------
  1319.  */
  1320. int 
  1321. Dev_GraphicsPutc(c)
  1322. register char c;
  1323. {
  1324.     MASTER_LOCK(&graphicsMutex);
  1325.  
  1326.     if (initialized && (displayType == PMAGBA)) {
  1327.     Blitc((unsigned char)(c & 0xff));
  1328.     } else {
  1329.     if (isascii(c)) {
  1330.         mach_MonFuncs.mputchar(c);
  1331.     }
  1332.     }
  1333.  
  1334.     MASTER_UNLOCK(&graphicsMutex);
  1335.  
  1336.     return(1);
  1337. }
  1338.  
  1339.  
  1340. /*
  1341.  *----------------------------------------------------------------------
  1342.  *
  1343.  * Blitc --
  1344.  *
  1345.  *    Write a character to the screen.
  1346.  *
  1347.  * Results:
  1348.  *    None.
  1349.  *
  1350.  * Side effects:
  1351.  *    None.
  1352.  *
  1353.  *----------------------------------------------------------------------
  1354.  */
  1355. static void
  1356. Blitc(c)
  1357.     register unsigned char c;
  1358. {
  1359.     register char *bRow, *fRow;
  1360.     register int i;
  1361.     register int ote = 1024; /* offset to table entry */
  1362.     int colMult = 8;
  1363.     extern char devFont[];
  1364.  
  1365.     c &= 0xff;
  1366.  
  1367.     switch ( c ) {
  1368.     case '\t':
  1369.         for(i = 8 - (scrInfoPtr->col & 0x7); i > 0; i--) {
  1370.         Blitc(' ');
  1371.         }
  1372.         break;
  1373.     case '\r':
  1374.         scrInfoPtr->col = 0;
  1375.         break;
  1376.     case '\b':
  1377.         scrInfoPtr->col--;
  1378.         if(scrInfoPtr->col < 0) {
  1379.         scrInfoPtr->col = 0;
  1380.         }
  1381.         break;
  1382.     case '\n':
  1383.         if(scrInfoPtr->row + 1 >= scrInfoPtr->maxRow) {
  1384.         Scroll();
  1385.         } else {
  1386.         scrInfoPtr->row++;
  1387.         }
  1388.         scrInfoPtr->col = 0;
  1389.         break;
  1390.     case '\007':
  1391.         DevDC7085KBDPutc(LK_RING_BELL);
  1392.         break;
  1393.     default:
  1394.         /*
  1395.          * If the next character will wrap around then 
  1396.          * increment row counter or scroll screen.
  1397.          */
  1398.         if (scrInfoPtr->col >= scrInfoPtr->maxCol) {
  1399.         scrInfoPtr->col = 0;
  1400.         if(scrInfoPtr->row + 1 >= scrInfoPtr->maxRow) {
  1401.             Scroll();
  1402.         } else {
  1403.             scrInfoPtr->row++;
  1404.         }
  1405.         }
  1406.         /*
  1407.          * xA1 to XFD are the printable characters added with 8-bit
  1408.          * support.
  1409.          */
  1410.         if ((c >= ' ' && c <= '~') || (c >= 0xA1 && c <= 0xFD)) {
  1411.         bRow = frameBuffer + (scrInfoPtr->row * 15 & 0x3ff) * ote + 
  1412.                scrInfoPtr->col * colMult;
  1413.         i = c - ' ';
  1414.         if(i < 0 || i > 221) {
  1415.             i = 0;
  1416.         } else {
  1417.             /* These are to skip the (32) 8-bit 
  1418.              * control chars, as well as DEL 
  1419.              * and 0xA0 which aren't printable */
  1420.             if (c > '~') {
  1421.             i -= 34; 
  1422.             }
  1423.             i *= 15;
  1424.         }
  1425.         fRow = (char *)((int)devFont + i);
  1426.  
  1427.         /* inline expansion for speed */
  1428.         {
  1429.             int j;
  1430.             unsigned int *pInt;
  1431.  
  1432.             pInt = (unsigned int *) bRow;
  1433.             for(j = 0; j < 15; j++) {
  1434.             /*
  1435.              * fontmaskBits converts a nibble
  1436.              * (4 bytes) to a long word 
  1437.              * containing 4 pixels corresponding
  1438.              * to each bit in the nibble.  Thus
  1439.              * we write two longwords for each
  1440.              * byte in font.
  1441.              * 
  1442.              * Remember the font is 8 bits wide
  1443.              * and 15 bits high.
  1444.              *
  1445.              * We add 256 to the pointer to
  1446.              * point to the pixel on the 
  1447.              * next scan line
  1448.              * directly below the current
  1449.              * pixel.
  1450.              */
  1451.             *pInt =  fontmaskBits[(*fRow)&0xf];
  1452.             *(pInt+1)= fontmaskBits[((*fRow)>>4)&0xf];
  1453.             fRow++; 
  1454.             pInt += 256;
  1455.             }
  1456.         }
  1457.         scrInfoPtr->col++; /* increment column counter */
  1458.     }
  1459.     }
  1460.     if (!devGraphicsOpen) {
  1461.     PosCursor(scrInfoPtr->col * 8, scrInfoPtr->row * 15);
  1462.     }
  1463. }
  1464.  
  1465.  
  1466. /*
  1467.  *----------------------------------------------------------------------
  1468.  *
  1469.  * DevGraphicsOpen --
  1470.  *
  1471.  *    Open the graphics device.
  1472.  *
  1473.  * Results:
  1474.  *    None.
  1475.  *
  1476.  * Side effects:
  1477.  *    None.
  1478.  *
  1479.  *----------------------------------------------------------------------
  1480.  */
  1481. /*ARGSUSED*/
  1482. ReturnStatus
  1483. DevGraphicsOpen(devicePtr, useFlags, inNotifyToken, flagsPtr)
  1484.     Fs_Device *devicePtr;    /* Specifies type and unit number. */
  1485.     int useFlags;        /* Flags from the stream being opened */
  1486.     ClientData inNotifyToken;    /* Used for Fs call-back to notify waiting
  1487.                  * processes that the console device is ready.*/
  1488.     int        *flagsPtr;    /* Device open flags. */
  1489. {
  1490.     Time        time;
  1491.     ReturnStatus    status = SUCCESS;
  1492.  
  1493.     MASTER_LOCK(&graphicsMutex);
  1494.  
  1495.     if (displayType != PMAGBA) {
  1496.     status = DEV_NO_DEVICE;
  1497.     goto exit;
  1498.     }
  1499.     if (devicePtr->unit == DEV_MOUSE_UNIT) {
  1500.     if (devGraphicsOpen) {
  1501.         status = FS_FILE_BUSY;
  1502.         goto exit;
  1503.     }
  1504.     devGraphicsOpen = TRUE;
  1505.     devDivertXInput = FALSE;
  1506.     notifyToken = inNotifyToken;
  1507.     InitColorMap();
  1508.     /*
  1509.      * Set up event queue for later
  1510.      */
  1511.     scrInfoPtr->eventQueue.events = events;
  1512.     scrInfoPtr->eventQueue.tcs = tcs;
  1513.     scrInfoPtr->cursorBits = (short *)(cursorBits);
  1514.     scrInfoPtr->bitmap = (Address) (frameBuffer);
  1515.     scrInfoPtr->eventQueue.eSize = DEV_MAXEVQ;
  1516.     scrInfoPtr->eventQueue.eHead = scrInfoPtr->eventQueue.eTail = 0;
  1517.     scrInfoPtr->eventQueue.tcSize = MOTION_BUFFER_SIZE;
  1518.     scrInfoPtr->eventQueue.tcNext = 0;
  1519.     Timer_GetRealTimeOfDay(&time, (int *) NIL, (Boolean *) NIL);
  1520.     scrInfoPtr->eventQueue.timestampMS = TO_MS(time);
  1521.     }
  1522. exit:
  1523.     MASTER_UNLOCK(&graphicsMutex);
  1524.     return(status);
  1525. }
  1526.  
  1527.  
  1528. /*
  1529.  *----------------------------------------------------------------------
  1530.  *
  1531.  * DevGraphicsClose --
  1532.  *
  1533.  *    Close the graphics device.
  1534.  *
  1535.  * Results:
  1536.  *    None.
  1537.  *
  1538.  * Side effects:
  1539.  *    None.
  1540.  *
  1541.  *----------------------------------------------------------------------
  1542.  */
  1543. /*ARGSUSED*/
  1544. ReturnStatus
  1545. DevGraphicsClose(devicePtr, useFlags, openCount, writerCount)
  1546.     Fs_Device    *devicePtr;    /* Device information. */
  1547.     int        useFlags;    /* FS_READ | FS_WRITE */
  1548.     int        openCount;    /* Number of times still open. */
  1549.     int        writerCount;    /* Number of times still open for writing. */
  1550. {
  1551.     MASTER_LOCK(&graphicsMutex);
  1552.  
  1553.     if (devicePtr->unit == DEV_MOUSE_UNIT) {
  1554.     if (!devGraphicsOpen) {
  1555.         MASTER_UNLOCK(&graphicsMutex);
  1556.         return(FS_FILE_BUSY);
  1557.     }
  1558.     devGraphicsOpen = FALSE;
  1559.     InitColorMap();
  1560.     ScreenInit();
  1561.     VmMach_UserUnmap((Address) NIL);
  1562.     }
  1563.     MASTER_UNLOCK(&graphicsMutex);
  1564.     return(SUCCESS);
  1565. }
  1566.  
  1567.  
  1568. /*
  1569.  *----------------------------------------------------------------------
  1570.  *
  1571.  * DevGraphicsRead --
  1572.  *
  1573.  *    Read from the graphics device.
  1574.  *
  1575.  * Results:
  1576.  *    None.
  1577.  *
  1578.  * Side effects:
  1579.  *    None.
  1580.  *
  1581.  *----------------------------------------------------------------------
  1582.  */
  1583. /*ARGSUSED*/
  1584. ReturnStatus
  1585. DevGraphicsRead(devicePtr, readPtr, replyPtr)
  1586.     Fs_Device    *devicePtr;    /* Device to read from */
  1587.     Fs_IOParam    *readPtr;    /* Read parameter block */
  1588.     Fs_IOReply    *replyPtr;    /* Return length and signal */ 
  1589. {
  1590. }
  1591.  
  1592.  
  1593. /*
  1594.  *----------------------------------------------------------------------
  1595.  *
  1596.  * DevGraphicsWrite --
  1597.  *
  1598.  *    Write to the graphics device.
  1599.  *
  1600.  * Results:
  1601.  *    None.
  1602.  *
  1603.  * Side effects:
  1604.  *    None.
  1605.  *
  1606.  *----------------------------------------------------------------------
  1607.  */
  1608. /*ARGSUSED*/
  1609. ReturnStatus
  1610. DevGraphicsWrite(devicePtr, writePtr, replyPtr)
  1611.     Fs_Device    *devicePtr;    /* Indicates device */    
  1612.     Fs_IOParam    *writePtr;    /* Standard write parameter block */
  1613.     Fs_IOReply    *replyPtr;    /* Return length and signal */
  1614. {
  1615. }
  1616.  
  1617.  
  1618. /*
  1619.  *----------------------------------------------------------------------
  1620.  *
  1621.  * DevGraphicsIOControl --
  1622.  *
  1623.  *    Perform an io control on the graphics device.
  1624.  *
  1625.  * Results:
  1626.  *    None.
  1627.  *
  1628.  * Side effects:
  1629.  *    None.
  1630.  *
  1631.  *----------------------------------------------------------------------
  1632.  */
  1633. /*ARGSUSED*/
  1634. ReturnStatus
  1635. DevGraphicsIOControl(devicePtr, ioctlPtr, replyPtr)
  1636.     Fs_Device        *devicePtr;
  1637.     Fs_IOCParam        *ioctlPtr;
  1638.     Fs_IOReply        *replyPtr;
  1639. {
  1640.     ReturnStatus status = SUCCESS;
  1641.     int        isColor;
  1642.  
  1643.     MASTER_LOCK(&graphicsMutex);
  1644.  
  1645.     switch (ioctlPtr->command) {
  1646.     case IOC_GRAPHICS_GET_INFO: {
  1647.         char        *addr;
  1648.         /*
  1649.          * Map the screen info struct into the user's address space.
  1650.          */
  1651.         status = VmMach_UserMap(sizeof(DevScreenInfo), (Address) NIL,
  1652.         (Address)scrInfoPtr, FALSE, &addr);
  1653.         if (status != SUCCESS) {
  1654.         goto mapError;
  1655.         }
  1656.         bcopy((char *)&addr, ioctlPtr->outBuffer, sizeof(addr));
  1657.         /*
  1658.          * Map the events into the user's address space.
  1659.          */
  1660.         status = VmMach_UserMap(sizeof(eventsCached), (Address) NIL, 
  1661.             (Address)events, FALSE, &addr); 
  1662.         if (status != SUCCESS) {
  1663.         goto mapError;
  1664.         }
  1665.         scrInfoPtr->eventQueue.events = (DevEvent *)addr;
  1666.         /*
  1667.          * Map the tcs into the user's address space.
  1668.          */
  1669.         status = VmMach_UserMap(sizeof(tcsCached), (Address) NIL,
  1670.                 (Address)tcs, FALSE, &addr);
  1671.         if (status != SUCCESS) {
  1672.         goto mapError;
  1673.         }
  1674.         scrInfoPtr->eventQueue.tcs = (DevTimeCoord *)addr;
  1675.         /*
  1676.          * Map the plane mask into the user's address space.
  1677.          */
  1678.         status = VmMach_UserMap(sizeof(planeMask), (Address) NIL, 
  1679.             (Address)&planeMask, FALSE, &addr);
  1680.         if (status != SUCCESS) {
  1681.         goto mapError;
  1682.         }
  1683.         scrInfoPtr->planeMask = (char *)addr;
  1684.         /*
  1685.          * Map the bitmap into the user's address space.
  1686.          */
  1687.         status = VmMach_UserMap(1024*1024, (Address) NIL,
  1688.                   (Address)scrInfoPtr->bitmap, FALSE, &addr);
  1689.         if (status != SUCCESS) {
  1690.         goto mapError;
  1691.         }
  1692.         scrInfoPtr->bitmap = (char *)addr;
  1693.         break;
  1694. mapError:    
  1695.         VmMach_UserUnmap((Address) NIL);
  1696.         status = FS_BUFFER_TOO_BIG;
  1697.         printf("Cannot map shared data structures\n");
  1698.         break;
  1699.     }
  1700.  
  1701.     case IOC_GRAPHICS_MOUSE_POS:
  1702.         /*
  1703.          * Set mouse state.
  1704.          */
  1705.         scrInfoPtr->mouse = *((DevCursor *)ioctlPtr->inBuffer);
  1706.         PosCursor(scrInfoPtr->mouse.x, scrInfoPtr->mouse.y );
  1707.         break;
  1708.  
  1709.     case IOC_GRAPHICS_INIT_SCREEN:    
  1710.         /*
  1711.          * Initialize the screen.
  1712.          */
  1713.         ScreenInit();
  1714.         break;
  1715.  
  1716.     case IOC_GRAPHICS_KBD_CMD: {
  1717.         DevKpCmd        *kpCmdPtr;
  1718.         unsigned char    *cp;
  1719.  
  1720.         kpCmdPtr = (DevKpCmd *)ioctlPtr->inBuffer;
  1721.         if (kpCmdPtr->nbytes == 0) {
  1722.         kpCmdPtr->cmd |= 0x80;
  1723.         }
  1724.         if (!devGraphicsOpen) {
  1725.         kpCmdPtr->cmd |= 1;
  1726.         }
  1727.         DevDC7085KBDPutc((int)kpCmdPtr->cmd);
  1728.         cp = &kpCmdPtr->par[0];
  1729.         for (cp = &kpCmdPtr->par[0]; 
  1730.              kpCmdPtr->nbytes > 0;
  1731.          cp++, kpCmdPtr->nbytes--) {
  1732.         if(kpCmdPtr->nbytes == 1) {
  1733.             *cp |= 0x80;
  1734.         }
  1735.         DevDC7085KBDPutc((int)*cp);
  1736.         }
  1737.         break;
  1738.     }
  1739.  
  1740.     case IOC_GRAPHICS_GET_INFO_ADDR:    
  1741.         *(DevScreenInfo **)ioctlPtr->outBuffer = scrInfoPtr;
  1742.         break;
  1743.  
  1744.     case IOC_GRAPHICS_CURSOR_BIT_MAP:
  1745.         LoadCursor((unsigned short *)ioctlPtr->inBuffer);
  1746.         break;
  1747.  
  1748.     case IOC_GRAPHICS_CURSOR_COLOR:
  1749.         CursorColor((unsigned int *)ioctlPtr->inBuffer);
  1750.         break;
  1751.          
  1752.         case IOC_GRAPHICS_COLOR_MAP:
  1753.         LoadColorMap((DevColorMap *)ioctlPtr->inBuffer);
  1754.         break;
  1755.  
  1756.     case IOC_GRAPHICS_KERN_LOOP: 
  1757.         printf("DevGraphicsIOControl: QIOKERNLOOP\n");
  1758.         break;
  1759.  
  1760.     case IOC_GRAPHICS_KERN_UNLOOP: 
  1761.         printf("DevGraphicsIOControl: QIOKERNUNLOOP\n");
  1762.         break;
  1763.  
  1764.     case IOC_GRAPHICS_VIDEO_ON:
  1765.         break;
  1766.  
  1767.     case IOC_GRAPHICS_VIDEO_OFF:
  1768.         break;
  1769.     case    IOC_GET_FLAGS:
  1770.     case    IOC_SET_FLAGS:
  1771.     case    IOC_SET_BITS:
  1772.     case    IOC_CLEAR_BITS:
  1773.         /*
  1774.          * No graphics specific bits are set this way.
  1775.          */
  1776.         break;
  1777.     case IOC_GRAPHICS_IS_COLOR:
  1778.         isColor = 1;
  1779.         bcopy((char *)&isColor, ioctlPtr->outBuffer, sizeof (int));
  1780.         break;
  1781.  
  1782.     default:
  1783.         printf("DevGraphicsIOControl: Unknown command %d\n", 
  1784.            ioctlPtr->command);
  1785.         status = FS_INVALID_ARG;
  1786.         break;
  1787.     }
  1788.  
  1789.     MASTER_UNLOCK(&graphicsMutex);
  1790.     return(status);
  1791. }
  1792.  
  1793.  
  1794. /*
  1795.  *----------------------------------------------------------------------
  1796.  *
  1797.  * DevGraphicsSelect --
  1798.  *
  1799.  *    Perform a select on the graphics device.
  1800.  *
  1801.  * Results:
  1802.  *    None.
  1803.  *
  1804.  * Side effects:
  1805.  *    None.
  1806.  *
  1807.  *----------------------------------------------------------------------
  1808.  */
  1809. ReturnStatus
  1810. DevGraphicsSelect(devicePtr, readPtr, writePtr, exceptPtr)
  1811.     Fs_Device            *devicePtr;
  1812.     int            *readPtr;
  1813.     int            *writePtr;
  1814.     int            *exceptPtr;
  1815. {
  1816.     ReturnStatus status = SUCCESS;
  1817.  
  1818.     MASTER_LOCK(&graphicsMutex);
  1819.  
  1820.     if (*readPtr) {
  1821.     if (devicePtr->unit == DEV_MOUSE_UNIT) {
  1822.         if (scrInfoPtr->eventQueue.eHead == scrInfoPtr->eventQueue.eTail) {
  1823.         *readPtr = 0;
  1824.         }
  1825.     } else {
  1826.         *readPtr = 0;
  1827.     }
  1828.     }
  1829.  
  1830.     MASTER_UNLOCK(&graphicsMutex);
  1831.  
  1832.     *writePtr = *exceptPtr = 0;
  1833.  
  1834.     return(status);
  1835. }
  1836.  
  1837.  
  1838.  
  1839. /*
  1840.  *----------------------------------------------------------------------
  1841.  *
  1842.  * Dev_VidEnable --
  1843.  *
  1844.  *    Enables or disables the video display.
  1845.  *
  1846.  * Results:
  1847.  *    None.
  1848.  *
  1849.  * Side effects:
  1850.  *    Turns video on or off.
  1851.  *
  1852.  *----------------------------------------------------------------------
  1853.  */
  1854. /*ARGSUSED*/
  1855. ReturnStatus
  1856. Dev_VidEnable(onOff)
  1857. Boolean onOff;        /* TRUE if video is to be on. */
  1858. {
  1859.     return(SUCCESS);
  1860. }
  1861.